package com.lenovo.tool;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Properties;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;


public class TranslationImporter {
    // Compare target and src XML files, and then import those elements
    // with translations from src XML file to target XML
    // file
    private static void importTranslationsToFile(File target, File src) {
        try {
            Document targetDoc = DocumentUtils.openDocument(target);
            HashMap<String, Element> targetMap = XmlResUtil.parseXml(targetDoc);

            Document srcDoc = DocumentUtils.openDocument(src);
            HashMap<String, Element> srcMap = XmlResUtil.parseXml(srcDoc);

            Iterator<String> itor = srcMap.keySet().iterator();
            while (itor.hasNext()) {
                String key = itor.next();

                if (targetMap.containsKey(key)) {
                    String tv = targetMap.get(key).getTextContent();
                    String sv = srcMap.get(key).getTextContent();
                    if (tv != null && sv != null && !tv.equals(sv)) {
                        Node newNode = targetDoc.importNode(srcMap.get(key),
                                true);
                        Node oldNode = targetMap.get(key);
                        Node parent = oldNode.getParentNode();
                        parent.replaceChild(newNode, oldNode);
                    }
                }
            }

            itor = srcMap.keySet().iterator();
            while (itor.hasNext()) {
                String key = itor.next();

                if (!(targetMap.containsKey(key))) {
                    Node newNode = targetDoc.importNode(srcMap.get(key), true);
                    Node parent = targetDoc.getDocumentElement();
                    parent.appendChild(targetDoc.createTextNode("    "));
                    parent.appendChild(newNode);
                    parent.appendChild(targetDoc.createTextNode("\n"));
                }
            }

            AttributesHandler srcHandler = new AttributesHandler();
            AttributesHandler targetHandler = new AttributesHandler();

            SAXParserFactory fac = SAXParserFactory.newInstance();
            SAXParser parser = fac.newSAXParser();
            parser.parse(src, srcHandler);
            parser.parse(target, targetHandler);

            HashMap<String, AttributesImpl> attrMap = new HashMap<String, AttributesImpl>();
            attrMap.putAll(srcHandler.getAttributeMap());
            attrMap.putAll(targetHandler.getAttributeMap());

            StreamResult result = new StreamResult(target);
            SAXTransformerFactory sff = (SAXTransformerFactory) SAXTransformerFactory
                    .newInstance();
            TransformerHandler th = sff.newTransformerHandler();

            Transformer tf = th.getTransformer();
            tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
            th.setResult(result);

            XmlResUtil.transformNode(DocumentUtils.isSameLine(target), th, targetDoc, attrMap, null);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (TransformerException e) {
            e.printStackTrace();
        }

    }

    public static void importTranslations(File targetDir, File srcDir)
            throws IOException {
        int srcPathLen = srcDir.getAbsolutePath().length();

        XmlResFileFilter filter = new XmlResFileFilter(true);
        ArrayList<File> srcFiles = filter.getAllXmlResFiles(srcDir);

        for (File srcFile : srcFiles) {
            String path = srcFile.getAbsolutePath().substring(srcPathLen + 1);

            File targetFile = new File(targetDir, path);
            if (targetFile.exists()) {
                importTranslationsToFile(targetFile, srcFile);
            } else {
                if (XmlResUtil.createNewFile(targetFile)) {
                    XmlResUtil.copyFile(srcFile, targetFile);
                }
            }
        }
    }

    public static void main(String[] args) {
        if (args.length != 1) {
            System.out.println("please enter the config file name");
            return;
        }

        File configFile = new File(args[0]);
        if (!configFile.exists() || !configFile.isFile()) {
            System.out.println("config file error");
            return;
        }

        try {
            PropConfigHandler handler = new PropConfigHandler();

            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser parser = factory.newSAXParser();
            parser.parse(configFile, handler);

            Properties props = handler.getProps();

            File targetDir = new File(props.getProperty("targetdir"));
            File srcDir = new File(props.getProperty("srcdir"));

            importTranslations(targetDir, srcDir);
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
